Applications in a computer system typically do not have access to low level statistical data from the operating system about the application. The statistic data may identify a number of instructions retired by the application or the resource utilization by the application, for example. To obtain statistical data, application developers often resort to intrusive methods of gathering statistical data such as profiling the execution of the application or making rough approximations about the execution of the application. Unfortunately, the use of intrusive methods of gathering statistical data generally affects the outcome of the experiment (i.e., the observation changes the performance of the application) and the use of approximations may provide crude or unusable data.
In applications that implement concurrent programming (viz., interaction between multiple execution contexts such as threads, fibers (i.e., lightweight threads), and child processes), shared data is typically synchronized. When an execution context accesses data, it generally invokes a lock or other synchronization technique to ensure that no other execution context performs a conflicting access to the data. The synchronization prevents data from being corrupted but adds processing overhead to each data access. Perhaps more importantly, the synchronization often serializes the access to the data by different execution contexts. This serialization may inhibit the performance and scalability of a process, particularly where there are many independent processing resources that execute execution contexts.